template<std::uint8_t _Element_size, std::uint8_t _Count>
struct attribute_set
{
    static_assert(_Element_size > 0 && _Count > 0, "Invalid attribute set size");
    static constexpr std::uint32_t count = _Count;
    alignas(_Element_size) std::byte data[_Element_size * _Count];

    template<typename T> requires (sizeof(T) <= _Element_size)
    void get(T& out, std::uint32_t index) const noexcept {
        static_assert(sizeof(T) <= _Element_size, "Type is too large for attribute set");
        static_assert(alignof(T) <= _Element_size, "Alignment of type is too large for attribute set");
        std::memcpy(&out, data + index * _Element_size, sizeof(T));
    };

    template<typename T> requires (sizeof(T) <= _Element_size)
    void set(const T& in, std::uint32_t index){
        static_assert(sizeof(T) <= _Element_size, "Type is too large for attribute set");
        static_assert(alignof(T) <= _Element_size, "Alignment of type is too large for attribute set");
        std::memcpy(data + index * _Element_size, &in, sizeof(T));
    };
};


template<typename... Args>
class PolyAttr {
protected:
    std::tuple<Args...> attr;
public:
    template<std::size_t ElementSize, std::size_t Count >
    void set_attribute(const attribute_set<ElementSize, Count>& attrs) {
        [&] <std::size_t... Is>(std::index_sequence<Is...>) {
            (attrs.get(std::get<Is>(attr), Is), ...);
        }(std::make_index_sequence< std::min(Count, std::tuple_size_v<decltype(attr)>) >{});
    }
};

struct TestClass : PolyAttr<std::uint32_t, std::uint64_t, double> {
};